from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession

from app.core import security
from app.db import session
from app.schemas import user as user_schema
from app.schemas import auth as auth_schema
from app.services import auth as auth_service

router = APIRouter(tags=["Authentication"])

@router.post("/register", response_model=user_schema.User)
async def register_user(
    user_in: user_schema.UserCreate,
    db: Annotated[AsyncSession, Depends(session.get_db)]
):
    """Register a new user. Requires email verification afterwards."""
    # Note: register_new_user handles username/email duplication check
    # It also currently sets user to inactive. Add verification email logic.
    db_user = await auth_service.register_new_user(db=db, user_in=user_in)
    # TODO: Send verification email
    return db_user

@router.post("/login", response_model=auth_schema.Token)
async def login_for_access_token(
    form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
    db: Annotated[AsyncSession, Depends(session.get_db)]
):
    """Login user and return a JWT access token."""
    user = await auth_service.authenticate_user(
        db, username=form_data.username, password=form_data.password
    )
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    if not user.is_active: # Optional: enforce email verification before login
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Inactive user. Please verify your email first."
        )

    access_token = security.create_access_token(
        subject=user.username # Use username as subject in JWT
    )
    return {"access_token": access_token, "token_type": "bearer"}

# TODO: Add endpoints for email verification, password reset request, and setting new password
